using System;
using System.Web;
using System.Web.UI.WebControls.WebParts;
using System.Web.Hosting;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using System.Data;

namespace Blazing.Web.WebParts
{
    public class XmlFileSharedPersonalizationProvider : PersonalizationProvider
    {
        private const string ENCODED_PAGESETTINGS_TAG = "PageSettings";
        private string configFile = HttpContext.Current.Request.MapPath("~/App_Data/pageSettings.xml");
        private DataTable currentTable = null;
        public bool isGlobal = false;

        protected DataTable loadPageSettings()
        {
            if (currentTable == null)
            {
                DataSet ds = new DataSet();

                if (File.Exists(configFile))
                {
                    ds.ReadXml(configFile);
                    currentTable = ds.Tables["PageSettings"];
                    ds.Tables.Remove(currentTable);
                }
                else
                {
                    currentTable = new DataTable("PageSettings");
                    currentTable.Columns.Add("Path");
                    currentTable.Columns.Add("Blob");
                }
            }
            return currentTable;
        }

        protected void savePageSettings()
        {
            DataTable settings = loadPageSettings();
            DataSet ds = null;
            if (settings.DataSet == null)
            {
                ds = new DataSet("SharedState");
                ds.Tables.Add(settings);
            }
            else
                ds = settings.DataSet;
            
            ds.WriteXml(configFile);       
        }

        protected string getPageSettings(string pagePath)
        {
            DataTable settings = loadPageSettings();
            foreach (DataRow r in settings.Rows)
            {
                if ((string)r["Path"] == pagePath)
                {
                    return r["Blob"] as string;
                }
            }
            return string.Empty;
        }

        protected void updatePageSetting(string pagePath, string blob)
        {
            DataTable settings = @currentTable;

            foreach (DataRow r in settings.Rows)
            {
                if ((string)r["Path"] == pagePath)
                {
                    r["Blob"] = blob;
                    return;
                }
            }
            DataRow row = settings.NewRow();
            row["Path"] = pagePath;
            row["Blob"] = blob;
            settings.Rows.Add(row);
            settings.AcceptChanges();
       
        }

        // NOTE: only Shared-scope personalization is loaded
        protected override void LoadPersonalizationBlobs(
          WebPartManager webPartManager,
          string path,
          string userName,
          ref byte[] sharedDataBlob,
          ref byte[] userDataBlob)
        {
            //check if cached pagesettings exist
            object cachedPageSettings = HttpContext.Current.Cache[ENCODED_PAGESETTINGS_TAG + ":" + path];
            if (cachedPageSettings != null)
            {
                sharedDataBlob = (byte[])cachedPageSettings;
            }
            else
            {
                string fullPath = HttpContext.Current.Request.MapPath(path);

                if (isGlobal)
                    fullPath = "Global";

                    sharedDataBlob = System.Convert.FromBase64String(getPageSettings(fullPath));

                    //store in Cache (with a dependency to current config file)
                    webPartManager.Page.Cache.Insert(ENCODED_PAGESETTINGS_TAG + ":" + path,
                    sharedDataBlob, new System.Web.Caching.CacheDependency(configFile));
            }
        }

        protected override void ResetPersonalizationBlob(
          WebPartManager webPartManager,
          string path,
          string userName)
        {
        }

        // NOTE: only Shared-scope personalization is saved
        protected override void SavePersonalizationBlob(
          WebPartManager webPartManager,
          string path,
          string userName,
          byte[] dataBlob)
        {
            if (userName == null)
            {
               string fullPath = HttpContext.Current.Request.MapPath(path);

               if (isGlobal)
                   fullPath = "Global";

               updatePageSetting(fullPath, System.Convert.ToBase64String(dataBlob));
               savePageSettings();

            }
        }

        private string _applicationName;
        public override string ApplicationName
        {
            get
            {
                if (string.IsNullOrEmpty(_applicationName))
                {
                    _applicationName = HostingEnvironment.ApplicationVirtualPath;
                }
                return _applicationName;
            }
            set
            {
                _applicationName = value;
            }
        }

        public override int GetCountOfState(
          PersonalizationScope scope,
          PersonalizationStateQuery query)
        {
            return 0;
        }

        public override PersonalizationStateInfoCollection FindState(
          PersonalizationScope scope,
          PersonalizationStateQuery query,
          int pageIndex,
          int pageSize,
          out int totalRecords)
        {
            totalRecords = 0;
            return null;
        }

        public override int ResetState(
          PersonalizationScope scope,
          string[] paths,
          string[] usernames)
        {
            return 0;
        }

        public override int ResetUserState(
          string path,
          DateTime userInactiveSinceDate)
        {
            return 0;
        }
    }
}
